#ifndef _CACHE_H_
#define _CACHE_H_

#include "systemc.h"

#define C_BLOCKS 32
#define _OFFEND  (_offset + 31)

/*
 * NOTES:
 *   din_src: H => CPU ;; L => MH
 *
 *   When din_src is HIGH write is issued by cpu, so dirty bit
 *   will be set HIGH. In addition _offset will be considered
 *   to write just one word.
 *
 */
class cache : sc_module
{
  sc_lv<128> _mem[C_BLOCKS];
  sc_lv<25>  _tab[C_BLOCKS];

  unsigned   _tag;
  unsigned   _index;
  unsigned   _offset;

public:
  sc_in< sc_logic >   cs;
  sc_in< sc_logic >   rw;

  sc_in< sc_lv<32> >  addr;
  sc_in< sc_lv<32> >  din0;
  sc_in< sc_lv<32> >  din1;
  sc_in< sc_lv<32> >  din2;
  sc_in< sc_lv<32> >  din3;
  sc_in< sc_logic >   set_v;   
  sc_in< sc_logic >   din_src; // says when dirty bit is HIGH
  sc_in< sc_logic >   block; // says when just one block is written

  sc_out< sc_logic >  rdy;
  sc_out< sc_logic >  hit;
  sc_out< sc_lv<25> > tout;
  sc_out< sc_lv<32> > dout0;
  sc_out< sc_lv<32> > dout1;
  sc_out< sc_lv<32> > dout2;
  sc_out< sc_lv<32> > dout3;

  SC_CTOR (cache)
  {
    for (int i = 0; i < C_BLOCKS; i++) {
      _mem[i] = 0;
      _tab[i] = 0;
    }

    rdy.initialize(SC_LOGIC_1);
    hit.initialize(SC_LOGIC_0);
    tout.initialize(0);
    dout0.initialize(0);
    dout1.initialize(0);
    dout2.initialize(0);
    dout3.initialize(0);

    SC_THREAD (compute);
    sensitive << cs << rw << addr 
              << din0 << din1 << din2 << din3 
              << set_v << din_src;
  }

  void compute(void);

};

#endif /* _CACHE_H_ */
